package com.sdry.service.impl.jyy;
import java.io.File;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.UUID;

import javax.annotation.Resource;
import javax.servlet.http.HttpSession;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import com.sdry.mapper.barCodeOperation.BarCodeOperationMapper;
import com.sdry.mapper.jyy.ReceiveDetailMapper;
import com.sdry.mapper.jyy.ReceiveMapper;
import com.sdry.mapper.jyy.UpMapper;
import com.sdry.mapper.lz.MaterielMapper;
import com.sdry.mapper.tdd.emailRecord.EmailRecordMapper;
import com.sdry.model.barCodeOperation.BarCodeOperation;
import com.sdry.model.jyy.Receive;
import com.sdry.model.jyy.ReceiveDetail;
import com.sdry.model.jyy.ReceiveDetailInstock;
import com.sdry.model.jyy.Up;
import com.sdry.model.lz.CodeMark;
import com.sdry.model.lz.Customer;
import com.sdry.model.lz.LzQueryCriteria;
import com.sdry.model.lz.Materiel;
import com.sdry.model.lz.ReceiveMark;
import com.sdry.model.lz.WarehouseRegion;
import com.sdry.model.tdd.emailRecord.EmailRecord;
import com.sdry.model.zc.ZcInventoryInfoEntity;
import com.sdry.model.zc.ZcMaterielAndTrayEntity;
import com.sdry.service.jyy.UpService;
import com.sdry.service.zc.ZcBindAndUnbindService;
import com.sdry.utils.DateUtil;
import com.sdry.web.controller.jyy.AppJyController;

/**
 *
 *@ClassName: UpService
 *@Description: 入库记录
 *@Author jyy
 *@Date 2019-05-17 17:20:06
 *@version 1.0
 *
 *修改人：连雷明
 *修改时间：2019-11-08
 *修改内容：给方法selectByMid2，129行，加参数，仓库ID
*/
@Service
@Transactional(rollbackFor = Exception.class)
public class UpServiceImpl implements UpService {

	private final static Logger log = LoggerFactory.getLogger(AppJyController.class);
    private final static int AFFECT_ROW = 0;
    //图片上传路径
    String imgLog = "";
	@Resource
	UpMapper upMapper;
	@Resource
	ReceiveMapper receiveMapper;
	@Resource
	ReceiveDetailMapper receiveDetailMapper;
	@Resource
	MaterielMapper materielMapper;
	@Resource
	BarCodeOperationMapper barCodeOperationMapper;
	@Resource
	EmailRecordMapper emailRecordMapper;
	@Resource
    ZcBindAndUnbindService zcBindAndUnbindService;
	/**
	 * 根据主键id查询实体
	 *
	 * @param id 主键id
	 * @return 实体
	 */
	public Up queryById(Long id) {
		return upMapper.queryById(id);
	}

	/**
	 * 条件查询所有
	 *
	 * @param param 实体条件
	 * @return 实体集合
	 */
	public List<Up> queryAllByMution(Up param) {
		return upMapper.queryAllByMution(param);
	}

	/**
	 * 条件分页查询
	 *
	 * @param param 实体条件
	 * @return 实体集合
	 */
	public List<Up> findPageByMution(Up param) {
		return upMapper.findPageByMution(param);
	}

	/**
	 * 条件查询记录数
	 *
	 * @param param 实体条件
	 * @return 实体集合
	 */
	public Integer selectCountByMution(Up param) {
		return upMapper.selectCountByMution(param);
	}

	/**
	 * 插入返回id
	 *
	 * @param param 实体条件
	 * @return 主键id
	 */
	public Long insert(Up param) {
		return upMapper.insert(param);
	}

	/**
	 * 根据主键更新 返回影响行数
	 *
	 * @param param 实体条件
	 * @return 影响行数
	 */
	public Integer update(Up param) {
		return upMapper.update(param);
	}

	/**
	 * 根据主键拼接的字符串删除返回影响行数
	 *
	 * @param ids 主键拼接的字符串
	 * @return 影响行数
	 */
	public Integer delete(String ids) {
		return upMapper.delete(ids);
	}

	/**
	 * 新增物料库存对应关系信息
	 */
	@Override
	public Long insertMw(Up up) {
		return upMapper.insertMw(up);
	}

	/**
	 * 根据仓库名称查询仓库id
	 *
	 * @param cqname 仓库名称
	 * @return 仓库id
	 */
	@Override
	public Long getwidByWname(String cqname) {
		return upMapper.getwidByWname(cqname);
	}

	/**
	 * 根据物料id查询库存信息
	 *
	 * @param mid 料id
	 * @return
	 */
	@Override
	public ZcInventoryInfoEntity selectByMid(String mid, String batch_num, String warehouse_id) {
		return upMapper.selectByMid(mid, batch_num, warehouse_id);
	}

	/**
	 * 根据物料ID，批次，仓库ID，查库存
	 *
	 * @param mid         物料ID
	 * @param batch_num   批次
	 * @param warehouseId 仓库ID
	 * @return llm 19.11.08 添加参数，warehouseId
	 */
	@Override
	public ZcInventoryInfoEntity selectByMid2(String mid, String batch_num, String warehouseId) {
		return upMapper.selectByMid2(mid, batch_num, warehouseId);
	}

	/**
	 * 修改库存信息
	 *
	 * @return
	 */
	@Override
	public Long editStock(ZcInventoryInfoEntity zcInventoryInfoEntity) {
		return upMapper.editStock(zcInventoryInfoEntity);
	}

	/**
	 * 修改库存信息(计数)
	 *
	 * @return
	 */
	@Override
	public Long editStockOnlyCount(ZcInventoryInfoEntity zcInventoryInfoEntity) {
		return upMapper.editStockOnlyCount(zcInventoryInfoEntity);
	}

	/**
	 * 根据产品码和规格型号查询物料
	 *
	 * @return
	 */
	@Override
	public Materiel queryMaterielByRemarkAndSpecification(String remark, String materiel_size, String materiel_properties) {
		return upMapper.queryMaterielByRemarkAndSpecification(remark, materiel_size, materiel_properties);
	}

	/**
	 * 根据库区id查找库区名称
	 *
	 * @param region_id
	 * @return
	 */
	@Override
	public WarehouseRegion queryRegionNameById(Long region_id) {
		return upMapper.queryRegionNameById(region_id);
	}

	/**
	 * 分页查询已收货未入库
	 *
	 * @param criteria
	 */
	@Override
	public List<ReceiveDetailInstock> queryReceiveDetailInstockCriteria(LzQueryCriteria criteria) {
		return upMapper.queryReceiveDetailInstockCriteria(criteria);
	}

	/**
	 * 查询已收货未入库的数量
	 *
	 * @param criteria
	 * @return
	 */
	@Override
	public int countReceiveDetailInstockCriteria(LzQueryCriteria criteria) {
		return upMapper.countReceiveDetailInstockCriteria(criteria);
	}

	/**
	 * 添加库存信息
	 *
	 * @param zcInventoryInfoEntity
	 */
	@Override
	public Long insertStock(ZcInventoryInfoEntity zcInventoryInfoEntity) {
		return upMapper.insertStock(zcInventoryInfoEntity);
	}

	/**
	 * 添加库存信息（计数）
	 *
	 * @param zcInventoryInfoEntity
	 */
	@Override
	public Long insertStockOnlyCount(ZcInventoryInfoEntity zcInventoryInfoEntity) {
		return upMapper.insertStockOnlyCount(zcInventoryInfoEntity);
	}

	/**
	 * 给不良品绑定条码
	 *
	 * @param receiveDetail
	 */
	@Override
	public void bingdNGCode(ReceiveDetail receiveDetail) {
		upMapper.bingdNGCode(receiveDetail);
	}

	/**
	 * 减去已收货未入库数量
	 *
	 * @param final_value
	 */
	@Override
	public void updateReceiveDetailInstockCodeNum(Long id, Long final_value) {
		upMapper.updateReceiveDetailInstockCodeNum(id, final_value);
	}

	/**
	 * 根据供应商id查询供应商的邮箱
	 *
	 * @param customer_id
	 * @return
	 */
	@Override
	public Customer queryCustomerEmailById(Long customer_id) {
		return upMapper.queryCustomerEmailById(customer_id);
	}

	/**
	 * app收货提交
	 * @param Details 收货详细
	 * @param person 收货人id
	 * @param pic_key 图片上传路径
	 * @param sure_name 回收容器数量
	 * @param response
	 * @param session
	 * @return
	 */
	@Override
	public Integer submitReceive(String Details, String person, List<MultipartFile> pic_key,
							  String sure_name, Long warehouse_id) {
        
		//1、调用文件上传的方法
		//imgUpload(session, pic_key);
		//计数循环次数，作用：如果实际收货数量和预计收货数量不相等就不改变收货单状态
		//int count = 0;
		String addStr = "";
		Integer affect4 = 0;
		CodeMark codeMark = null;
		Gson gson = new Gson();
		//接收APP传过来的数据
		List<ReceiveDetail> receiveDetailList = gson.fromJson(Details, new TypeToken<List<ReceiveDetail>>() {}.getType());
		log.info("APP收货提交时传递的参数：Details的条数=" + receiveDetailList.size() + ",提交人的id=" + person +
                ",容器回收的数量=" + sure_name + ",仓库id=" + warehouse_id);
		//2、如果是供应商码，把条码存入receiveMark表
		//insertCustomerCode(warehouse_id, receiveDetailList);
		//遍历receiveDetailList
		for (ReceiveDetail receiveDetail : receiveDetailList) {
			Integer totalLinearLong = 0;
			/*for (int i = 0; i < receiveDetail.getReceiveCode().size(); i++) {
				//获取该种物料的每个条码对应的线长之和
				totalLinearLong += receiveDetail.getReceiveCode().get(i).getNum();
			}*/
			//根据物料id查询物料
			Materiel materiel = materielMapper.queryMaterielById(receiveDetail.getMid());
			//获取收货单里的线重
			Float numbers = receiveDetail.getCodeNum();
            receiveDetail.setCodeNum(numbers);
            //8、根据app提交数量修改收货详细表
            Integer affact = receiveDetailMapper.update(receiveDetail);
			//先根据物料id和批次查询条码库存是否存在
			//lz新增warehouse_id
			ZcInventoryInfoEntity zcInventoryInfoEntity = upMapper.selectByMid(receiveDetail.getMid() + "",
                    receiveDetail.getPici(), warehouse_id + "");
			//如果存在
			if (zcInventoryInfoEntity != null) {
				//根据物料id和批次查询的库存数量
				Integer mNum = zcInventoryInfoEntity.getmNum();
				//根据物料id和批次查询的库存数量+收货单里的每个条码包含的数量
				//mNum = totalLinearLong + mNum;
				mNum = receiveDetail.getNgNum() + mNum;
				//总数量（个数）
				zcInventoryInfoEntity.setmNum(mNum);
				//3、修改库存
				Long affact1 = upMapper.editStock(zcInventoryInfoEntity);
				//4、将邮件推送信息存入数据库
				//insertEmailInfo(warehouse_id, materiel, zcInventoryInfoEntity);
			} else {
				//如果不存在
				ZcInventoryInfoEntity zcInventoryInfoEntity1 = new ZcInventoryInfoEntity();
				zcInventoryInfoEntity1.setMid(receiveDetail.getMid());
				zcInventoryInfoEntity1.setmNum(receiveDetail.getNgNum());
				zcInventoryInfoEntity1.setmBatch(receiveDetail.getPici());
				zcInventoryInfoEntity1.setEnterPerson(Long.parseLong(person));
				//lz添加
				zcInventoryInfoEntity1.setWarehouse_id(warehouse_id);
				//3、新增库存
				Long affact2 = upMapper.insertStock(zcInventoryInfoEntity1);
				//4、将邮件推送信息存入数据库
				//insertEmailInfo(warehouse_id, materiel, zcInventoryInfoEntity1);
			}
			//先判断是否第一次有提交收货总数为零的，如果没有才能进入质检表
			int sum = 0;
			for (int i = 0; i < receiveDetail.getReceiveCode().size(); i++) {
				sum += receiveDetail.getReceiveCode().get(i).getNum();
			}
			if (sum > 0) {
				String receiveNumber = receiveDetail.getReceiveNumber();
				Receive param = new Receive();
				param.setReceiveNumber(receiveNumber);
				List<Receive> receive = receiveMapper.queryAllByMution(param);
				//如果不质检或者是发货退的
				if (materiel.getIs_check() == 1 || "1".equals(receive.get(0).getType())) {
					//receiveDetail.setCodeNum(sum);
					receiveDetail.setRemark(receiveDetail.getId() + "");
					receiveDetail.setStatus(1);
					SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
					receiveDetail.setCheck_date(sdf.format(new Date()));
					//lz新增warehouse_id
					receiveDetail.setWarehouse_id(warehouse_id);
					//5、给质检表新增数据
					Long indentity1 = receiveDetailMapper.addReceiveDetailQuality1(receiveDetail);
					for (int j = 0; j < receiveDetail.getReceiveCode().size(); j++) {
						codeMark = new CodeMark();
						//修改的收货单详细表的id
						codeMark.setReceive_detail_id(indentity1);
						codeMark.setCode(receiveDetail.getReceiveCode().get(j).getCode());
						codeMark.setNum(receiveDetail.getReceiveCode().get(j).getNum());
						codeMark.setIs_ng(receiveDetail.getReceiveCode().get(j).getIs_ng());
						//lz增加线重
                        codeMark.setLinear_weight(receiveDetail.getReceiveCode().get(j).getLinear_weight());
						//6、给CodeMark绑定条码
						receiveDetailMapper.addCodeMark(codeMark);
						addStr += receiveDetail.getReceiveCode().get(j).getCode() + ",";
						SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
						String time = format.format(new Date());
						BarCodeOperation bar = new BarCodeOperation();
						bar.setBarCode(receiveDetail.getReceiveCode().get(j).getCode());
						bar.setCodeNum(receiveDetail.getReceiveCode().get(j).getNum());
						bar.setBatch(receiveDetail.getPici());
						bar.setOperator(Long.parseLong(person));
						bar.setOperatingTime(time);
						bar.setMaterielId(receiveDetail.getMid());
						bar.setLocationId2("待上架区");
						bar.setType("质检");
						bar.setResult("成功");
						//lz新增warehouse_id
						bar.setWarehouse_id(warehouse_id);
						//7、给历史记录表插入数据
						barCodeOperationMapper.insert(bar);
					}
				}
				/*else {
					//如果质检
					receiveDetail.setCodeNum(sum);
					receiveDetail.setRemark(receiveDetail.getId() + "");
					receiveDetail.setStatus(0);
					SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
					receiveDetail.setCheck_date(sdf.format(new Date()));
					//lz新增warehouse_id
					receiveDetail.setWarehouse_id(warehouse_id);
					//5、给质检表新增数据
					Long indentity2 = receiveDetailMapper.addReceiveDetailQuality(receiveDetail);
					for (int j = 0; j < receiveDetail.getReceiveCode().size(); j++) {
						codeMark = new CodeMark();
						codeMark.setReceive_detail_id(indentity2);
						codeMark.setCode(receiveDetail.getReceiveCode().get(j).getCode());
						codeMark.setNum(receiveDetail.getReceiveCode().get(j).getNum());
						codeMark.setIs_ng(receiveDetail.getReceiveCode().get(j).getIs_ng());
						//6、给CodeMark绑定条码
						receiveDetailMapper.addCodeMark(codeMark);
						addStr += receiveDetail.getReceiveCode().get(j).getCode() + ",";
						SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
						String time = format.format(new Date());
						BarCodeOperation bar = new BarCodeOperation();
						bar.setBarCode(receiveDetail.getReceiveCode().get(j).getCode());
						bar.setCodeNum(receiveDetail.getReceiveCode().get(j).getNum());
						bar.setBatch(receiveDetail.getPici());
						bar.setOperator(Long.parseLong(person));
						bar.setOperatingTime(time);
						bar.setMaterielId(receiveDetail.getMid());
						bar.setType("质检");
						bar.setResult("成功");
						//lz新增warehouse_id
						bar.setWarehouse_id(Long.parseLong(warehouse_id));
						//7、给历史记录表插入数据
						barCodeOperationService.insert(bar);
					}
				}*/
			}

			//遍历预计线重和实际线重，匹配上则修改收货单状态，匹配不上则不改状态
			/*if (receiveDetail.getRcode() == receiveDetail.getCodeNum()) {
				count++;
			}*/
		}
		Date date = new Date();
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
		ZcMaterielAndTrayEntity zcMaterielAndTrayEntity = new ZcMaterielAndTrayEntity();
		String tray_code = System.currentTimeMillis() + "";
		zcMaterielAndTrayEntity.setTray_code(tray_code);
		zcMaterielAndTrayEntity.setMateriel_code(addStr);
		zcMaterielAndTrayEntity.setBinding_person(Long.parseLong(person));
		zcMaterielAndTrayEntity.setBinding_date(sdf.format(date));
		zcMaterielAndTrayEntity.setTargetRegion("待上架区");
		//zcMaterielAndTrayEntity.setLocation_code(location_code);
		//9、到待上架区
		int affact3 = zcBindAndUnbindService.bindAndUp2SpecialArea(zcMaterielAndTrayEntity, warehouse_id);
		ReceiveDetail receiveDetail = receiveDetailList.get(0);
		Receive receive = new Receive();
		receive.setReceiveNumber(receiveDetail.getReceiveNumber());
		//lz添加warehouse_id
		receive.setWarehouse_id(warehouse_id);
		List<Receive> receives = receiveMapper.queryAllByMution(receive);
		//9、如果每条记录都匹配，则修改状态
		//if (count == receiveDetailList.size()) {
		//获取收货单号
		Receive receive2 = receives.get(0);
		receive2.setState(1);
		receive2.setReceiveDate(DateUtil.dateFormat3());
		receive2.setReceiveName(person);
		//回收容器数量
		receive2.setSureName(sure_name);
		receive2.setImgLog(imgLog);
		//lz添加warehouse_id
		receive2.setWarehouse_id(warehouse_id);
		//10、更改收货单状态为已收货
		affect4 = receiveMapper.update(receive2);
		/*} else {
			//获取收货单号
			Receive receive2 = receives.get(0);
			receive2.setReceiveDate(DateUtil.dateFormat3());
			receive2.setReceiveName(person);
			//回收容器数量
			receive2.setSureName(sure_name);
			receive2.setImgLog(imgLog);
			//lz添加warehouse_id
			receive2.setWarehouse_id(warehouse_id);
			//10、更改收货单状态为已收货
            affect4 = receiveMapper.update(receive2);
		}*/

		SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		for (ReceiveDetail detail : receiveDetailList) {
			BarCodeOperation bar = new BarCodeOperation();
			bar.setBatch(detail.getPici());
			bar.setOperator(Long.parseLong(person));
			bar.setOperatingTime(sdf2.format(date));
			bar.setMaterielId(detail.getMid());
			bar.setLocationId2("待上架区");
			bar.setType("收货");
            //lz新增warehouse_id
            bar.setWarehouse_id(warehouse_id);
            //如果收货单修改则成功
            if (affect4 > AFFECT_ROW) {
                bar.setResult("成功");
            } else {
                bar.setResult("失败");
            }
            for (CodeMark codeMark2 : detail.getReceiveCode()) {
                bar.setBarCode(codeMark2.getCode());
                bar.setCodeNum(codeMark2.getNum());
                //11、给历史记录表插入数据
                barCodeOperationMapper.insert(bar);
            }
		}
		return affect4;
	}

	/**
	 * 图片上传
	 * @param session session
	 * @param pic_key 图片上传文件名
	 */
	public void imgUpload(HttpSession session, List<MultipartFile> pic_key) {
		if(pic_key.size() > AFFECT_ROW){
			for(MultipartFile f : pic_key){
				if(f != null){
					// 1.获取原文件名1
					String oriName = f.getOriginalFilename();
					// 2.获取原文件图片后缀，以最后的.作为截取(.jpg)1
					String extName = oriName.substring(oriName.lastIndexOf("."));
					// 3.生成自定义的新文件名，这里以UUID.jpg|png|xxx作为格式（可选操作，也可以不自定义新文件名）1
					String uuid = UUID.randomUUID().toString();
					//组合成新的文件
					String newName = uuid + extName;
					// 4.获取要保存的路径文件夹
					String realPath = session.getServletContext().getRealPath("/images/");
					// 5.保存
					String savePath = realPath + "\\" +  newName;
					imgLog = "/images/" + newName;
					File desFile = new File(savePath);
					try {
						f.transferTo(desFile);
					} catch (Exception e) {
						log.info("LZ图片上传的方法出现异常");
						e.printStackTrace();
					}
				}
			}
		}
	}

	/**
	 * 如果是供应商码，把条码存入receiveMark表
	 * @param warehouse_id 仓库id
	 * @param receiveDetailList 收货详情集合
	 */
	public void insertCustomerCode(Long warehouse_id, List<ReceiveDetail> receiveDetailList) {
		log.info("如果是供应商码，把条码存入receiveMark表的仓库id=" + warehouse_id);
		String receiveNumber = receiveDetailList.get(0).getReceiveNumber();
		Receive receive = new Receive();
		receive.setReceiveNumber(receiveNumber);
		//lz新增warehouse_id
		receive.setWarehouse_id(warehouse_id);
		List<Receive> list = receiveMapper.queryAllByMution(receive);
		if(list.size() > AFFECT_ROW){
			int bt = list.get(0).getBarcode();
			if(bt == 1){
				for (ReceiveDetail receiveDetail : receiveDetailList) {
					for (CodeMark cm : receiveDetail.getReceiveCode()) {
						ReceiveMark receiveMark = new ReceiveMark();
						receiveMark.setCode(cm.getCode());
						receiveMark.setNum(cm.getNum());
						receiveMark.setReceive_detail_id(receiveDetail.getId());
						receiveMark.setSAP_QAD(receiveDetail.getMateriel_num());
						//lz新增warehouse_id
						receiveMark.setWarehouse_id(warehouse_id);
						receiveDetailMapper.addReceiveMark(receiveMark);
					}
				}
			}
		}
	}

	/**
	 * 将邮件推送信息存入数据库
	 * @param materiel 物料实体
	 * @param zcInventoryInfoEntity 库存实体
	 */
	public void insertEmailInfo(Long warehouse_id, Materiel materiel, ZcInventoryInfoEntity zcInventoryInfoEntity) {
		//如果库存大于或小于预警值  报警
		String content = "";
		if (materiel != null) {
			String materiel_num = materiel.getMateriel_num();
			//String materiel_name = materiel.getMateriel_name();
			//String people = "";
			if(zcInventoryInfoEntity.getmNum() != null && materiel.getUpper_value() != null) {
				if (zcInventoryInfoEntity.getmNum() >= materiel.getUpper_value()) {
					content = materiel_num + "库存" + zcInventoryInfoEntity.getmNum() + "大于等于" + materiel.getUpper_value() + "特此报警";
					//PushExample.testSendPush(content , "库存报警", people, "0");
				} else if (zcInventoryInfoEntity.getmNum() <= materiel.getLower_value()) {
					content = materiel_num + "库存" + zcInventoryInfoEntity.getmNum() + "低于等于" + materiel.getLower_value() + "特此报警";
					//PushExample.testSendPush(content , "库存报警", people, "0");
				}

				//根据供应商id查询供应商的邮箱
				Customer customer = upMapper.queryCustomerEmailById(materiel.getCustomer_id());
				if (customer != null && !"".equals(content)) {
					EmailRecord emailRecord = new EmailRecord();
					emailRecord.setOperate("入库");
					emailRecord.setReceivePeopleId(customer.getId());
					emailRecord.setReceiveDate(DateUtil.dateFormat3());
					emailRecord.setEmailContent(content);
					emailRecord.setRemark("0");
					//lz新增warehouse_id
					emailRecord.setWarehouse_id(warehouse_id);
					//4、将邮件推送信息存入数据库
					emailRecordMapper.insert(emailRecord);
				}
			}
		}
	}
}
